#ifndef __MACROS_H__
#define __MACROS_H__

//========================debug相关定义
#define BOCHS_DEBUG_POINT




//========================gdt相关定义
#define TSSINDEX 10
#define GDTNUM 64
#define SELECTOR_IDX(no) ((no) << 3)
#define NULL_SEG_IDX SELECTOR_IDX(0)
#define SYS_CODE64_IDX SELECTOR_IDX(1)
#define SYS_DATA64_IDX SELECTOR_IDX(2)
#define USER_CODE64_IDX SELECTOR_IDX(3)
#define USER_DATA64_IDX SELECTOR_IDX(4)
#define SYS_CODE32_IDX SELECTOR_IDX(5)
#define SYS_DATA32_IDX SELECTOR_IDX(6)
#define USER_CODE32_IDX SELECTOR_IDX(7)
#define USER_DATA32_IDX SELECTOR_IDX(8)
#define TSS_SELECTOR_IDX SELECTOR_IDX(10)

// GdtTable[0] 空段
// GdtTable[1] 系统代码段 64
// GdtTable[2] 系统数据段 64
// GdtTable[3] 用户代码段 64
// GdtTable[4] 用户数据段 64
// GdtTable[5] 系统代码段 32
// GdtTable[6] 系统数据段 32
// GdtTable[7] 用户代码段 32
// GdtTable[8] 用户数据段 32
#define LOAD_GDTR(limit, addr)          \
    do                                  \
    {                                   \
        __asm__ __volatile__(           \
            "movw %%ax, -10(%%rsp)\n\t" \
            "movq %%rbx, -8(%%rsp)\n\t" \
            "lgdt -10(%%rsp)"           \
            :                           \
            : "a"(limit), "b"(addr)     \
            : "memory");                \
    } while (0)






//========================idt相关定义
#define IDTNUM 256
#define GET_FUNC_POINT(s) 0x88(s)
#define _set_gate(gate_selector_addr, attr, ist, code_addr)                                                 \
    do                                                                                                      \
    {                                                                                                       \
        unsigned long __d0/* code selector [%rax] */, __d1/* code_addr [%rdx] */;                           \
        __asm__ __volatile__("movw	%%dx,	%%ax	\n\t"                                                   \
                             "andq	$0x7,	%%rcx	\n\t"                                                   \
                             "addq	%4,	    %%rcx   \n\t"                                                   \
                             "shlq	$32,	%%rcx	\n\t"                                                   \
                             "addq	%%rcx,	%%rax	\n\t"                                                   \
                             "xorq	%%rcx,	%%rcx	\n\t"                                                   \
                             "movl	%%edx,	%%ecx	\n\t"                                                   \
                             "shrq	$16,	%%rcx	\n\t"                                                   \
                             "shlq	$48,	%%rcx	\n\t"                                                   \
                             "addq	%%rcx,	%%rax	\n\t"                                                   \
                             "movq	%%rax,	%0	    \n\t"                                                   \
                             "shrq	$32,	%%rdx	\n\t"                                                   \
                             "movq	%%rdx,	%1	    \n\t"                                                   \
                             : "=m"(*((unsigned long *)(gate_selector_addr))),                              \
                               "=m"(*(1 + (unsigned long *)(gate_selector_addr))), "=&a"(__d0), "=&d"(__d1) \
                             : "i"(attr << 8),                                                              \
                               "3"((unsigned long *)(code_addr)), "2"(SYS_CODE64_IDX << 16), "c"(ist)       \
                             : "memory");                                                                   \
    } while (0)


#define LOAD_IDTR(limit, addr)          \
    do                                  \
    {                                   \
        __asm__ __volatile__(           \
            "movw %%ax, -10(%%rsp)\n\t" \
            "movq %%rbx, -8(%%rsp)\n\t" \
            "lidt -10(%%rsp)"           \
            :                           \
            : "a"(limit), "b"(addr)     \
            : "memory");                \
    } while (0)






//========================tss相关定义
#define IST_BASE_ADDR 0x9f000
#define LOAD_TR(offset)       \
    do                        \
    {                         \
        __asm__ __volatile__( \
            "ltr %%ax"        \
            :                 \
            : "a"(offset)     \
            : "memory");      \
    } while (0)







//========================虚拟内存相关定义
#define SYSTEM_PML4_ADDR 0x101000
#define SYSTEM_PDPT_ADDR (SYSTEM_PML4_ADDR + 0x1000)
#define SYSTEM_PDT_ADDR (SYSTEM_PDPT_ADDR + 0x1000)







//========================公共相关定义
#define KERNEL_BASE 0xffff800000000000
#define KERNEL_BUFF_MAX_SIZE 8192
#define NULL ((void *)0)









//========================内存结构相关定义
#define MAX_MEM_SIZE 64




//========================字符串相关定义
#define LEFT 0x01
#define PLUS 0x02
#define SPACE 0x04
#define SPECIAL 0x10
#define ZEROPAD 0x20
#define SMALL 0x40
#define SIGN 0x80
#define is_digit(x) ((x) >= '0' && (x) <= '9')
#define do_div(n, base) ({                                              \
int __res;                                                              \
__asm__("divq %%rcx":"=a" (n),"=d" (__res):"0" (n),"1" (0),"c" (base)); \
__res; })

//========================打印字符相关定义
#define COLOR_BLUE    0x000000ff
#define COLOR_RED     0x00ff0000
#define COLOR_GREEN   0x0000ff00
#define COLOR_YELLOW  0x00ffff00
#define COLOR_WHITE   0x00ffffff
#define COLOR_BLACK   0x00000000

#endif